home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / Terminal 2.2 / Project / Sources / FormatStr.c < prev    next >
Text File  |  1992-01-17  |  6KB  |  240 lines

  1. /*
  2.     Terminal 2.2
  3.     "FormatStr.c"
  4.  
  5.     In the spirit of printf() but using pascal strings.
  6.  
  7.     Format specifiers begin with the character % and include zero or more
  8.     of the following conversion specification elements:
  9.  
  10.     % [justify flag] [0 pad character] [field size] [type of variable]
  11.  
  12.     Justify flag (optional):
  13.         -    Left justify output in field, pad on right (default is to
  14.             right justify).
  15.     Pad character (optional):
  16.         0    Use zero rather than space (default) for the pad character.
  17.     Type of variable:
  18.         i    int
  19.         l    long
  20.         c    single character
  21.         s    pascal string
  22.         a    character array
  23.         %    print a %, no argument used
  24.         
  25. */
  26.  
  27. #ifdef THINK_C
  28. #include "MacHeaders"
  29. #endif
  30. #ifdef applec
  31. #pragma load ":(Objects):MacHeadersMPW"
  32. #pragma segment Main2
  33. #endif
  34.  
  35. Byte *FormatStr(Byte *string, Byte *template);
  36. Byte *SFormatStr(Byte *string, Byte *template, long *param);
  37.  
  38. static void MoveBytes(
  39.     register Byte *source,
  40.     register Byte **destination,
  41.     register Byte *limit,
  42.     register short count)
  43. {
  44.     while (*destination <= limit && count--)
  45.         *(*destination)++ = *source++;
  46. }
  47.  
  48. static void MoveBlanks(
  49.     register Byte **destination,
  50.     register Byte *limit,
  51.     register short count,
  52.     register Byte pad)
  53. {
  54.     if (count <= 0)
  55.         return;
  56.     while (*destination <= limit && count--)
  57.         *(*destination)++ = pad;
  58. }
  59.  
  60. Byte *FormatStr(
  61.     Byte *result,            /* Result string */
  62.     Byte *template)            /* Template string */
  63. {
  64.     va_list ap;
  65.     Byte *p = result + 1;
  66.     Byte *max = template + *template;
  67.     Byte num[30];
  68.     short fieldWidth;
  69.     Byte pad;
  70.     Boolean leftJustify;
  71.  
  72.     va_start(ap, template);
  73.  
  74.     while (template < max) {
  75.         template++;
  76.         if (*template == '%') {
  77.             template++;
  78.             fieldWidth = 0;
  79.             leftJustify = FALSE;
  80.             pad = ' ';
  81.             if (*template == '-') {
  82.                 template++;
  83.                 leftJustify = TRUE;
  84.             }
  85.             if (*template >= '0' && *template <= '9') {
  86.                 if (*template == '0')
  87.                     pad = '0';
  88.                 do
  89.                     fieldWidth = 10*fieldWidth + (*template++ & 0x0F);
  90.                 while (*template >= '0' && *template <= '9');
  91.             }
  92.             switch (*template) {
  93.                 case 'a':            /* Character array */
  94.                     MoveBytes(va_arg(ap, Byte *), &p, result + 255, fieldWidth);
  95.                     break;
  96.                 case 'c':            /* Character */
  97.                     {
  98.                         Byte c;
  99.  
  100.                         if (!leftJustify)
  101.                             MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  102. #ifdef applec
  103.                         /* In MPW C char is passed in 4 bytes on the stack! */
  104.                         c = va_arg(ap, long);
  105. #else
  106.                         /* In THINK C char is passed in 2 bytes on the stack! */
  107.                         c = va_arg(ap, short);
  108. #endif
  109.                         MoveBytes(&c, &p, result + 255, 1);
  110.                         if (leftJustify)
  111.                             MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  112.                         }
  113.                     break;
  114.                 case 's':            /* String */
  115.                     {
  116.                         register Byte *sp;
  117.  
  118.                         sp = va_arg(ap, Byte *);
  119.                         if (!leftJustify)
  120.                             MoveBlanks(&p, result + 255, fieldWidth - *sp,
  121.                                 pad);
  122.                         MoveBytes(sp + 1, &p, result + 255, *sp);
  123.                         if (leftJustify)
  124.                             MoveBlanks(&p, result + 255, fieldWidth - *sp,
  125.                                 pad);
  126.                     }
  127.                     break;
  128.                 case 'i':            /* int */
  129. #ifdef applec
  130.                     /* In MPW C short is passed in 4 bytes on the stack! */
  131. #else
  132.                     NumToString(va_arg(ap, short), num);
  133.                     goto integer;
  134. #endif
  135.                 case 'l':            /* long */
  136.                     NumToString(va_arg(ap, long), num);
  137.                 integer:
  138.                     if (!leftJustify)
  139.                         MoveBlanks(&p, result + 255, fieldWidth - *num,
  140.                             pad);
  141.                     MoveBytes(num + 1, &p, result + 255, *num);
  142.                     if (leftJustify)
  143.                         MoveBlanks(&p, result + 255, fieldWidth - *num,
  144.                             pad);
  145.                     break;
  146.                 default:
  147.                     *p++ = *template;
  148.             }
  149.         } else                        /* Copy character */
  150.             *p++ = *template;
  151.     }
  152.     va_end(pa);
  153.     *result = p - result - 1;
  154.     return result;
  155. }
  156.  
  157. Byte *SFormatStr(                /* Special version for scripts */
  158.     Byte *result,                /* Result string (Pascal string) */
  159.     register Byte *template,    /* Template string (C-string) */
  160.     long params[])                /* Array with parameters (char, long or C-string) */
  161. {
  162.     Byte *p = result + 1;
  163.     register long *s = params;
  164.     Byte num[30];
  165.     short fieldWidth;
  166.     Byte pad;
  167.     Boolean leftJustify;
  168.  
  169.     while (*template) {
  170.         if (*template == '%') {
  171.             template++;
  172.             if (!*template)
  173.                 break;
  174.             fieldWidth = 0;
  175.             leftJustify = FALSE;
  176.             pad = ' ';
  177.             if (*template == '-') {
  178.                 template++;
  179.                 if (!*template)
  180.                     break;
  181.                 leftJustify = TRUE;
  182.             }
  183.             if (*template >= '0' && *template <= '9') {
  184.                 if (*template == '0')
  185.                     pad = '0';
  186.                 do
  187.                     fieldWidth = 10*fieldWidth + (*template++ & 0x0F);
  188.                 while (*template >= '0' && *template <= '9');
  189.                 if (!*template)
  190.                     break;
  191.             }
  192.             switch (*template) {
  193.                 case 'c':            /* Character */
  194.                     if (!leftJustify)
  195.                         MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  196.                     MoveBytes((Byte *)s + 3, &p, result + 255, 1);
  197.                     if (leftJustify)
  198.                         MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  199.                     s++;
  200.                     break;
  201.                 case 's':            /* C-string */
  202.                     {
  203.                         register Byte *sp;
  204.  
  205.                         sp = (Byte *)*s;
  206.                         CtoPstr((char *)sp);
  207.                         if (!leftJustify)
  208.                             MoveBlanks(&p, result + 255, fieldWidth - *sp,
  209.                                 pad);
  210.                         MoveBytes(sp + 1, &p, result + 255, *sp);
  211.                         if (leftJustify)
  212.                             MoveBlanks(&p, result + 255, fieldWidth - *sp,
  213.                                 pad);
  214.                         PtoCstr((Byte *)sp);
  215.                     }
  216.                     s++;
  217.                     break;
  218.                 case 'i':            /* int */
  219.                     NumToString(*s, num);
  220.                     s++;
  221.                     if (!leftJustify)
  222.                         MoveBlanks(&p, result + 255, fieldWidth - *num,
  223.                             pad);
  224.                     MoveBytes(num + 1, &p, result + 255, *num);
  225.                     if (leftJustify)
  226.                         MoveBlanks(&p, result + 255, fieldWidth - *num,
  227.                             pad);
  228.                     break;
  229.                 default:
  230.                     *p++ = *template;
  231.             }
  232.         } else                        /* Copy character */
  233.             *p++ = *template;
  234.         template++;
  235.     }
  236. done:
  237.     *result = p - result - 1;
  238.     return result;
  239. }
  240.